home *** CD-ROM | disk | FTP | other *** search
- #define LIBQBUILD_CORE
- #include "../include/libqbuild.h"
-
- int outleafs = 0; // 4
-
- struct portal *prevleaknode; // 4
- FILE *leakfile; // 4
-
- int hit_occupied = 0; // 4
- int backdraw = 0; // 4
- /* PROGRESS-ONLY! */
- int outsidenum;
- int outsidecur;
-
- /*
- * ===========
- * PointInLeaf
- * ===========
- */
- struct node *PointInLeaf(__memBase, struct node * node, vec3_t point)
- {
- vec_t d;
-
- if (node->contents)
- return node;
-
- #ifdef EXHAUSIVE_CHECK
- if(node->planenum >= bspMem->numbrushplanes || node->planennum < 0)
- Error("looking for nonexisting plane %d\n", node->planenum);
- #endif
- d = DotProduct(bspMem->brushplanes[node->planenum].normal, point) - bspMem->brushplanes[node->planenum].dist;
-
- if (d > 0)
- return PointInLeaf(bspMem, node->children[0], point);
-
- return PointInLeaf(bspMem, node->children[1], point);
- }
-
- /*
- * ===========
- * PlaceOccupant
- * ===========
- */
- bool PlaceOccupant(__memBase, register int num, register vec3_t point, register struct node * headnode)
- {
- struct node *n;
-
- n = PointInLeaf(bspMem, headnode, point);
- if (n->contents == CONTENTS_SOLID)
- return FALSE;
- n->occupied = num;
- return TRUE;
- }
-
- /*
- * ==============
- * MarkLeakTrail
- * ==============
- */
- void MarkLeakTrail(register struct portal * n2)
- {
- int i;
- short int j;
- vec3_t p1, p2, dir;
- float len;
- struct portal *n1;
-
- if (hullnum)
- return;
-
- n1 = prevleaknode;
- prevleaknode = n2;
-
- if (!n1)
- return;
-
- VectorCopy(n2->winding->points[0], p1);
- for (i = 1; i < n2->winding->numpoints; i++) {
- for (j = 0; j < 3; j++)
- p1[j] = (p1[j] + n2->winding->points[i][j]) / 2;
- }
-
- VectorCopy(n1->winding->points[0], p2);
- for (i = 1; i < n1->winding->numpoints; i++) {
- for (j = 0; j < 3; j++)
- p2[j] = (p2[j] + n1->winding->points[i][j]) / 2;
- }
-
- VectorSubtract(p2, p1, dir);
- len = VectorLength(dir);
- VectorNormalize(dir);
-
- while (len > 2) {
- fprintf(leakfile, "%g %g %g\n", p1[0], p1[1], p1[2]);
- for (i = 0; i < 3; i++)
- p1[i] += dir[i] * 2;
- len -= 2;
- }
- }
-
- /*
- * ==================
- * RecursiveFillOutside
- *
- * If fill is FALSE, just check, don't fill
- * Returns TRUE if an occupied leaf is reached
- * ==================
- */
- bool RecursiveFillOutside(register struct node * l, register bool fill)
- {
- struct portal *p;
- int s;
-
- /* PROGRESS-ONLY! */
- if(fill == FALSE)
- outsidenum++;
- else
- mprogress(outsidenum, ++outsidecur);
-
- if (l->contents == CONTENTS_SOLID || l->contents == CONTENTS_SKY)
- return FALSE;
-
- if (l->valid == valid)
- return FALSE;
-
- if (l->occupied)
- return TRUE;
-
- l->valid = valid;
-
- // fill it and it's neighbors
- if (fill)
- l->contents = CONTENTS_SOLID;
- outleafs++;
-
- for (p = l->portals; p;) {
- s = (p->nodes[0] == l);
-
- if (RecursiveFillOutside(p->nodes[s], fill)) { // leaked, so stop filling
-
- if (backdraw-- > 0) {
- MarkLeakTrail(p);
- DrawLeaf(l, 2);
- }
- return TRUE;
- }
- p = p->next[!s];
- }
-
- return FALSE;
- }
-
- /*
- * ==================
- * ClearOutFaces
- *
- * ==================
- */
- void ClearOutFaces(register struct node * node)
- {
- struct visfacet **fp;
-
- if (node->planenum != -1) {
- ClearOutFaces(node->children[0]);
- ClearOutFaces(node->children[1]);
- return;
- }
- if (node->contents != CONTENTS_SOLID)
- return;
-
- for (fp = node->markfaces; *fp; fp++) {
- // mark all the original faces that are removed
- (*fp)->numpoints = 0;
- }
- node->faces = NULL;
- }
-
- //=============================================================================
-
- /*
- * ===========
- * FillOutside
- *
- * ===========
- */
- bool FillOutside(__memBase, struct node * node, char *pointfilename)
- {
- int s;
- vec_t *v;
- int i;
- bool inside;
-
- mprintf("----- FillOutside -------\n");
- /* PROGRESS-ONLY! */
- outsidenum = 0;
- outsidecur = 0;
-
- if (bspMem->bspOptions & QBSP_NOFILL) {
- mprintf(" - skipped\n");
- return FALSE;
- }
-
- inside = FALSE;
- for (i = 1; i < bspMem->nummapentities; i++) {
- if (!VectorZero(bspMem->mapentities[i].origin)) {
- if (PlaceOccupant(bspMem, i, bspMem->mapentities[i].origin, node))
- inside = TRUE;
- }
- }
-
- if (!inside) {
- mprintf("Hullnum %i: No bspMem->mapentities in empty space -- no filling performed\n", hullnum);
- return FALSE;
- }
-
- s = !(outside_node.portals->nodes[1] == &outside_node);
-
- // first check to see if an occupied leaf is hit
- outleafs = 0;
- valid++;
-
- prevleaknode = NULL;
-
- if (!hullnum) {
- leakfile = fopen(pointfilename, "w");
- if (!leakfile)
- Error("Couldn't open %s\n", pointfilename);
- }
-
- if (RecursiveFillOutside(outside_node.portals->nodes[s], FALSE)) {
- v = bspMem->mapentities[hit_occupied].origin;
- eprintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
- eprintf("reached occupant at: ( %g %g %g )\n"
- ,v[0], v[1], v[2]);
- eprintf("no filling performed\n");
- if (!hullnum)
- fclose(leakfile);
- eprintf("leak file written to %s\n", pointfilename);
- eprintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
- return FALSE;
- }
- if (!hullnum)
- fclose(leakfile);
-
- // now go back and fill things in
- valid++;
- RecursiveFillOutside(outside_node.portals->nodes[s], TRUE);
-
- // remove faces from filled in leafs
- ClearOutFaces(node);
-
- mprintf("%5i outleafs\n", outleafs);
- return TRUE;
- }
-